package com.appsky.drift.service;

import java.io.IOException;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.appsky.drift.R;
import com.appsky.drift.api.AppSkyApp;
import com.appsky.drift.api.DLog;
import com.appsky.drift.api.JsonFactory;
import com.appsky.drift.api.ServiceConnection;
import com.appsky.drift.api.UserInfo;
import com.appsky.drift.api.Utils;
import com.appsky.drift.async_task.LoginTask;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.Toast;

public class DriftService extends Service {

	private AppSkyApp app = null;

	private ServiceConnection connection = null;

	private boolean messageMonitorFlag = true;

	private Handler showToastHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			Bundle bundle = msg.getData();
			Toast.makeText(DriftService.this, bundle.getString("data"),
					bundle.getInt("duration")).show();
			super.handleMessage(msg);
		}

	};

	@Override
	public void onCreate() {
		DLog.i("Service is onCreate");
		app = (AppSkyApp) getApplication();

		LoginTask loginTask = new MyLoginTask(this);
		loginTask.execute("");

		super.onCreate();
	}

	@Override
	public void onStart(Intent intent, int startId) {
		DLog.i("Service is onStart");
		super.onStart(intent, startId);
	}

	@Override
	public void onDestroy() {
		messageMonitorFlag = false;
		if (connection != null) {
			connection.closeIOAndSocket();
		}
		if (app.isLogin()) {
			unregisterReceiver(sendMessageReceiver);
			app.setLoginState(false);
		}
		DLog.i("Service已销毁");
		super.onDestroy();
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	class MyLoginTask extends LoginTask {

		public MyLoginTask(Context context) {
			super(context);
		}

		@Override
		protected void onPreExecute() {
			initUserInfo();
			app.loginHandler.sendEmptyMessage(Utils.START_PROGRESS);
			super.onPreExecute();
		}

		@Override
		protected void onPostExecute(Integer flag) {
			app.loginHandler.sendEmptyMessage(flag);
			if (flag == Utils.LOGIN_SUCCESS || flag == Utils.REGISTER_SUCCESS) {
				app.setLoginState(true);
				try {
					connection = ServiceConnection.getConnection(app.getIp());
				} catch (IOException e) {
					e.printStackTrace();
				}
				startReceverMessageMonitorThread();
				IntentFilter filter = new IntentFilter(
						Utils.ACTION_SEND_MESSAGE);
				registerReceiver(sendMessageReceiver, filter);
			} else {
				DriftService.this.stopSelf();
			}
			super.onPostExecute(flag);
		}

	}

	private BroadcastReceiver sendMessageReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			DLog.i("发送一个消息！");
			String jsonString = intent.getStringExtra("json");
			sendMessageFromClient((jsonString));

		}
	};

	private void initUserInfo() {

		SharedPreferences globalPref = getSharedPreferences(Utils.PREF_GLOBAL,
				MODE_PRIVATE);

		resetLocation();

		app.myInfo.setNick(globalPref.getString(
				getString(R.string.pref_userNick),
				getString(R.string.default_nick)));
		app.myInfo.setSex(globalPref.getInt(getString(R.string.pref_userSex),
				2));
//		app.myInfo.setUserId(globalPref.getInt("userId", -1));
		app.myInfo.setUserId(-1);

	}

	private synchronized void resetLocation() {
		LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
			Location location = locationManager
					.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
			if (location != null) {
				// 这个加减会更准确，民间偏方...
				app.myInfo
				.setLatitude((int) (location.getLatitude() * 1000000 - 2500));
				app.myInfo
				.setLongitude((int) (location.getLongitude() * 1000000 + 4500));
			} else {
				DLog.e("location == null");
			}
		} else {
			DLog.i("network已关闭");
		}
	}

	private void startReceverMessageMonitorThread() {
		Thread monitorThread = new Thread() {
			@Override
			public void run() {
				String message = null;
				while (messageMonitorFlag) {
					DLog.i("正在读取监听到的消息");
					try {
						message = connection.readMessage();
						if (message != null) {
							DLog.i("监听到消息：" + message);
							handlingAndDispatchMessage(message);
						} else {
							messageMonitorFlag = false;
						}
					} catch (IOException e) {
						e.printStackTrace();
						messageMonitorFlag = false;
					}
				}
				DLog.i("消息监听已退出");
				super.run();
			}
		};
		monitorThread.start();
	}

	/**
	 * 统一处理收到的消息
	 * 
	 * @param message
	 */
	private void handlingAndDispatchMessage(String message) {
		JSONObject jsonObject = JSON.parseObject(message);
		String type = jsonObject.getString("type");
		jsonObject = jsonObject.getJSONObject("data");
		if (type != null) {
			if (type.equals(JsonFactory.TYPE_CHAT_CONTENT)) {
				handlingChatEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_ROOM_PERSON)) {
				handlingRoomPersonEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_ADD_NEARBY_PERSON)) {
				handlingAddNearbyPersonEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_REMOVE_NEARBY_PERSON)) {
				handlingRemoveNearbyPersonEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_INVITE_JOIN_ROOM)) {
				handlingInviteJoinRoomEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_JOIN_ROOM)) {
				handlingJoinRoomEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_QUIT_ROOM)) {
				handlingQuitRoomEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_UPDATE_USER_INFO)) {
				handlingUpdateUserInfoEvent(jsonObject);
			}
		}
	}

	private void handlingChatEvent(JSONObject jsonObject) {
		Intent intent = new Intent(Utils.ACTION_CHAT_MESSAGE_RECEIVER);
		intent.putExtra("json", jsonObject.toJSONString());
		sendBroadcast(intent);
	}

	private void handlingRoomPersonEvent(JSONObject jsonObject) {
		DLog.i("room_person" + jsonObject.toJSONString());
		app.myInfo.parseRoomPerson(jsonObject.getJSONArray("person_list"));
		app.obtainMessageHandler.sendEmptyMessage(0);
	}

	private void handlingAddNearbyPersonEvent(JSONObject jsonObject) {
		UserInfo user = app.myInfo.addNearbyPerson(jsonObject);
		DLog.i(user.getNick() + "上线");
		showToastOnService(user.getNick() + "上线，请刷新地图", Toast.LENGTH_SHORT);
	}

	private void handlingRemoveNearbyPersonEvent(JSONObject jsonObject) {
		int id = jsonObject.getIntValue("id");
		UserInfo user = app.myInfo.removeNearbyPerson(id);
		DLog.i(user.getNick() + "下线");
		showToastOnService(user.getNick() + "下线", Toast.LENGTH_SHORT);
	}

	private void handlingInviteJoinRoomEvent(JSONObject jsonObject) {
		int id = jsonObject.getIntValue("id");
		UserInfo owner = app.myInfo.getUserFromNearbyPerson(id);
		owner.setRoomId(id);
		String toast = null;
		toast = (owner.getSex() == 0) ? "邀请你加入她的房间" : "邀请你加入他的房间";
		showToastOnService(owner.getNick() + toast, Toast.LENGTH_SHORT);
		DLog.i(owner.getNick() + "邀请你加入他的房间");
	}

	private void handlingJoinRoomEvent(JSONObject jsonObject) {
		int id = jsonObject.getIntValue("id");
		int roomId = jsonObject.getIntValue("room_id");
		UserInfo user = app.myInfo.getUserFromNearbyPerson(id);
		user.setRoomId(roomId);
		if (roomId == app.myInfo.getRoomId()) {
			app.myInfo.addRoomPerson(user);
			showToastOnService(user.getNick() + "加入房间", Toast.LENGTH_SHORT);
		}
	}

	private void handlingQuitRoomEvent(JSONObject jsonObject) {
		int id = jsonObject.getIntValue("id");
		int roomId = jsonObject.getIntValue("room_id");
		UserInfo user = app.myInfo.getUserFromNearbyPerson(id);
		user.setRoomId(-1);
		if (roomId == app.myInfo.getRoomId()) {
			app.myInfo.removeRoomPerson(user);
			showToastOnService(user.getNick() + "离开房间", Toast.LENGTH_SHORT);
		}
	}
	
	private void handlingUpdateUserInfoEvent(JSONObject jsonObject) {
		
	}

	private void showToastOnService(String message, int duration) {
		Bundle bundle = new Bundle();
		bundle.putString("data", message);
		bundle.putInt("duration", duration);
		Message msg = new Message();
		msg.setData(bundle);
		showToastHandler.sendMessage(msg);
	}

	private void sendMessageFromClient(String message) {
		try {
			connection.sendMessage(message);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
